package com.eedi.framework.user.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.eedi.framework.user.controller.sys.vo.*;
import com.eedi.framework.biz.config.BizProperties;
import com.eedi.framework.common.enums.CommonStatusEnum;
import com.eedi.framework.common.enums.UserTypeEnum;
import com.eedi.framework.common.exception.util.PreconditionsUtils;
import com.eedi.framework.common.pojo.PageResult;
import com.eedi.framework.user.controller.sys.vo.*;
import com.eedi.framework.user.dal.mapper.SysUserMapper;
import com.eedi.framework.user.enums.SysUserErrorCodeConstants;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;

import static com.eedi.framework.common.exception.util.ServiceExceptionUtil.exception;

@Service
@Slf4j
public class SysUserServiceImpl implements SysUserService {
    @Resource
    private PasswordEncoder passwordEncoder;

    @Resource
    SysUserMapper sysUserMapper;

    @Resource
    BizProperties bizProperties;

    @Transactional
    @Override
    public SysUserLoginInfoResp create(SysUserAccountCreateReq createReq) {
        //检查登录ID
        SysUserLoginInfoResp byLoginId = sysUserMapper.selectByLoginId(createReq.getSysUserLoginId());
        PreconditionsUtils.checkArgument(byLoginId == null, SysUserErrorCodeConstants.SYS_USER_LOGIN_ID_EXISTS, createReq.getSysUserLoginId());
        //检查手机号
        if (StrUtil.isNotBlank(createReq.getSysUserMobile())) {
            SysUserLoginInfoResp byMobileAndRole = sysUserMapper.selectByMobileAndRole(createReq.getSysUserMobile(), UserTypeEnum.MEMBER_SYS);
            PreconditionsUtils.checkArgument(byMobileAndRole == null, SysUserErrorCodeConstants.SYS_USER_MOBILE_EXISTS, createReq.getSysUserLoginId());
        }
        //密码加密
        createReq.setSysUserPassword(passwordEncoder.encode(createReq.getSysUserPassword()));
        return sysUserMapper.create(createReq, CommonStatusEnum.ENABLE);
    }

    @Override
    public SysUserLoginInfoResp getLoginInfoByLoginId(String sysUserLoginId) {
        return selectByLoginId(sysUserLoginId);
    }

    @Override
    public boolean isPasswordMatch(String sysUserLoginId, String password) {
        String pwdByLoginId = getPwdByLoginId(sysUserLoginId);
        return passwordEncoder.matches(password, pwdByLoginId);
    }

    @Override
    public void updateUserLogin(String userId, String loginIp) {
        selectBySysUserId(userId);
        sysUserMapper.updateLoginTime(userId, loginIp);
    }

    @Override
    public PageResult<SysUserLoginInfoResp> page(SysUserAccountPageReq req) {
        return sysUserMapper.page(req);
    }

    @Override
    public PageResult<SysUserLoginInfoResp> page(SysUserAccountPageReq req, Collection<String> sysUserIds) {
        return sysUserMapper.page(req, sysUserIds);
    }

    @Override
    public SysUserLoginInfoResp selectByMobileAndRole(String mobile, UserTypeEnum userTypeEnum) {
        return sysUserMapper.selectByMobileAndRole(mobile, userTypeEnum);
    }


    @Override
    public SysUserLoginInfoResp selectByLoginId(String loginId) {
        return sysUserMapper.selectByLoginId(loginId);
    }

    @Override
    public SysUserLoginInfoResp selectBySysUserId(String sysUserId) {
        SysUserLoginInfoResp sysUserLoginResp = sysUserMapper.selectBySysUserId(sysUserId);
        PreconditionsUtils.checkNotNull(sysUserLoginResp, SysUserErrorCodeConstants.SYS_ACCOUNT_NOT_EXISTS);
        return sysUserLoginResp;
    }

    @Override
    public List<SysUserLoginInfoResp> selectBySysUserIds(Collection<String> sysUserIds) {
        if (CollUtil.isEmpty(sysUserIds)) {
            return List.of();
        }
        return sysUserMapper.selectBySysUserIds(sysUserIds);
    }

    @Override
    public SysUserLoginInfoResp selectBySysUserIdIgnoreStatus(String sysUserAccountId) {
        return sysUserMapper.selectByAccountIdIgnoreStatus(sysUserAccountId);
    }

    @Override
    public String resetPassword(String sysUserId) {
        SysUserLoginInfoResp sysUserLoginResp = selectBySysUserId(sysUserId);
        PreconditionsUtils.checkArgument(null != sysUserLoginResp, SysUserErrorCodeConstants.SYS_USER_NOT_EXISTS);
        sysUserMapper.resetPassword(sysUserId, encodePassword(bizProperties.getDefaultPasswd()));
        return bizProperties.getDefaultPasswd();
    }

    @Override
    public void resetMobile(SysUserAccountResetMobileReq req) {
        log.info("开始执行更新手机号操作，sysUserAccountId:{}, mobile:{}", req.getSysUserId(), req.getSysUserMobile());
        PreconditionsUtils.checkArgument(StringUtils.isNoneBlank(req.getSysUserId(), req.getSysUserMobile()), SysUserErrorCodeConstants.SYS_USER_ACCOUNT_OR_MOBILE_NULL);
        SysUserLoginInfoResp sysUserLoginResp = selectBySysUserId(req.getSysUserId());
        PreconditionsUtils.checkNotNull(sysUserLoginResp, SysUserErrorCodeConstants.SYS_USER_NOT_EXISTS);
        PreconditionsUtils.checkArgument(!req.getSysUserMobile().equals(sysUserLoginResp.getSysUserMobile()), SysUserErrorCodeConstants.SYS_USER_MOBILE_NO_CHANGE);

        log.info("开始查询手机号是否已被其他同类型账号使用，sysUserAccountId:{}, mobile:{}", req.getSysUserId(), req.getSysUserMobile());
        SysUserLoginInfoResp otherAccountDO = selectByMobileAndRole(req.getSysUserMobile(), sysUserLoginResp.getSysUserAccountType());
        PreconditionsUtils.checkArgument(otherAccountDO == null, SysUserErrorCodeConstants.SYS_USER_MOBILE_USED, req.getSysUserMobile());

        sysUserMapper.resetMobile(req.getSysUserId(), req.getSysUserMobile());
//        if (UserTypeEnum.MEMBER_DOCTOR.equals(sysUserLoginResp.getSysUserAccountType())) {
//            update.setSysUserLoginId(mobile);
//        }
//        sysUserAccountMapper.updateById(update);
    }

    @Override
    public void updateAccountStatus(String sysUserAccountId, CommonStatusEnum status) {
        SysUserLoginInfoResp sysUserLoginResp = selectBySysUserIdIgnoreStatus(sysUserAccountId);
        PreconditionsUtils.checkNotNull(sysUserLoginResp, SysUserErrorCodeConstants.SYS_ACCOUNT_NOT_EXISTS);
        sysUserMapper.updateStatusBySysUserAccountId(sysUserAccountId, status);
    }

    @Override
    public void updateSysUserInfo(SysUserUpReq req) {
        SysUserLoginInfoResp resp = selectBySysUserIdIgnoreStatus(req.getSysUserId());
        PreconditionsUtils.checkArgument(null != resp, SysUserErrorCodeConstants.SYS_USER_NOT_EXISTS);
        sysUserMapper.updateSysUserInfo(req);
    }

    @Override
    public void disableBySysUserAccountId(String sysUserAccountId) {
        SysUserLoginInfoResp sysUserLoginResp = selectBySysUserIdIgnoreStatus(sysUserAccountId);
        PreconditionsUtils.checkArgument(null != sysUserLoginResp, SysUserErrorCodeConstants.SYS_USER_NOT_EXISTS);
        if (CommonStatusEnum.DISABLE.equals(sysUserLoginResp.getSysUserAccountStatus())) {
            throw exception(SysUserErrorCodeConstants.SYS_USER_ACCOUNT_IS_DISABLE);
        }
        sysUserMapper.updateStatusBySysUserAccountId(sysUserAccountId, CommonStatusEnum.DISABLE);
    }

    @Override
    public void enableBySysUserAccountId(String sysUserAccountId) {
        SysUserLoginInfoResp sysUserLoginResp = selectBySysUserIdIgnoreStatus(sysUserAccountId);
        PreconditionsUtils.checkArgument(null != sysUserLoginResp, SysUserErrorCodeConstants.SYS_USER_NOT_EXISTS);
        if (CommonStatusEnum.ENABLE.equals(sysUserLoginResp.getSysUserAccountStatus())) {
            throw exception(SysUserErrorCodeConstants.SYS_USER_ACCOUNT_IS_ENABLE);
        }
        sysUserMapper.updateStatusBySysUserAccountId(sysUserAccountId, CommonStatusEnum.ENABLE);
    }

    @Override
    public String getPwdByLoginId(String sysUserLoginId) {
        return sysUserMapper.getPwdByLoginId(sysUserLoginId);
    }

    @Override
    public void editSysUserInfo(String sysUserId, SysUserProfileEditReq req) {
        selectBySysUserId(sysUserId);
        if (StrUtil.isNotBlank(req.getSysUserLoginId())) {
            SysUserLoginInfoResp sysUserLoginInfoResp = sysUserMapper.selectByLoginId(req.getSysUserLoginId());
            if (null != sysUserLoginInfoResp && !sysUserId.equals(sysUserLoginInfoResp.getSysUserId())) {
                throw exception(SysUserErrorCodeConstants.SYS_USER_LOGIN_ID_EXISTS);
            }
        }
        sysUserMapper.editUserInfo(sysUserId, req);
    }

    @Override
    public void editPwd(String sysUserId, SysUserProfileEditPwdReq req) {
        SysUserLoginInfoResp user = selectBySysUserId(sysUserId);
        PreconditionsUtils.checkArgument(isPasswordMatch(user.getSysUserLoginId(), req.getOldPwd()), SysUserErrorCodeConstants.SYS_USER_PASSWORD_FAILED);
        sysUserMapper.resetPassword(sysUserId, encodePassword(req.getNewPwd()));
    }

    @Override
    public Long countUser() {
        return sysUserMapper.countUser();
    }


//    @Override
//    public PageResult<DoctorAccountRespVO> getDoctorAccountPage(DoctorAccountPageReqVO pageReqVO) {
//        return memberAccountMapper.selectDoctorAccountPage(pageReqVO);
//    }

//    @Override
//    public PageResult<MemberUserAccountRespVO> getMemberUserAccountPage(MemberUserAccountPageReqVO pageReqVO) {
//        return memberAccountMapper.selectMemberUserAccountPage(pageReqVO);
//    }

    /**
     * 对密码进行加密
     *
     * @param password 密码
     * @return 加密后的密码
     */
    private String encodePassword(String password) {
        return passwordEncoder.encode(password);
    }
}
